﻿using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace VMExplorer
{
  class RemoteTypeWrapper<T> : TypeWrapper<T> where T:struct
  {
    #region Private fields

    private MemoryAddress _baseAddress;
    private SafeProcessHandle _hProcess;

    #endregion
    #region Construction

    protected RemoteTypeWrapper (SafeProcessHandle hProcess)
			: this (hProcess, MemoryAddress.Null)
    {
    }

		protected RemoteTypeWrapper (SafeProcessHandle hProcess, MemoryAddress baseAddress)
    {
      _hProcess = hProcess;
      _baseAddress = baseAddress;
      Inner = ReadStructure (hProcess, baseAddress);
    }

    public static T ReadStructure(SafeProcessHandle hProcess, MemoryAddress baseAddress)
    {
      T output = new T();

      if (baseAddress.IsValid)
      {
        int structSize = typeof (T).StructLayoutAttribute.Size;
        Trace.Assert (structSize != 0);

        IntPtr lpBuffer = Marshal.AllocHGlobal (structSize);
        try
        {
          if (RemoteReader.ReadMemory (hProcess, baseAddress, lpBuffer, (uint)structSize))
          {
            output = (T)Marshal.PtrToStructure (lpBuffer, typeof (T));
          }
        }
        finally
        {
          Marshal.FreeHGlobal (lpBuffer);
        }
      }

      return output;
    }

    #endregion
    #region Public Properties

    [Browsable(false)]
    public SafeProcessHandle ProcessHandle { get { return _hProcess; } }
    [Browsable(false)]
		public virtual MemoryAddress BaseAddress { get { return _baseAddress; } }

    #endregion
  }

}
